package org.ilc;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.ilc.message.MessageQueue;
import org.ilc.push.IDataProvider;
import org.ilc.push.ISendListener;
import org.ilc.push.ISendTask;
import org.ilc.push.ISessionListener;
import org.ilc.socketserver.Acceptor;
import org.ilc.task.SendTask;
import org.ilc.task.TaskQueue;
import org.ilc.util.BeanUtil;

import java.io.File;

import static org.ilc.Constants.*;

//import org.ilc.message.MessageQueue2;

/**
 * @author malongbo
 */
public class Context {
    private final Log log = LogFactory.getLog ("Context");
    private Acceptor acceptor;
    private ISendListener sendListener;
    private IDataProvider dataProvider;
    private ISendTask sendTask;
    private ISessionListener sessionListener;

    /**
     * 任务队列器
     */
    private TaskQueue taskQueue;

    /**
     * 消息队列器
     */
    private MessageQueue messageQueue;

    private  String dataDir;
    private  String confDir;
    private String workDir;
    private Config config;
    private Config appConfig;
    private String logDir;

    public void contextInitialize(String rootDir) throws Exception {
        confDir = rootDir.concat(File.separator).concat("conf");
        dataDir = rootDir.concat(File.separator).concat("data");
        workDir = rootDir.concat(File.separator).concat("work");
        logDir = rootDir.concat(File.separator).concat("logs");

        System.setProperty("server.conf.dir", confDir);
        System.setProperty("server.data.dir", dataDir);
        //配置文件
        config = Config.load(confDir.concat(File.separator).concat(CONFIG_NAME));
        appConfig = Config.load(confDir.concat(File.separator).concat(APP_CONFIG_NAME));

        initializeScoket();
        initializeInterface();
        initializeTaskQueue();
        initializeMessageQueue();
        //设置session 拦截器
        this.acceptor.setSessionListener(sessionListener);
    }

    /**
     * 初始化Socket服务器
     */
    void initializeScoket(){
        if(log.isDebugEnabled()){
            log.debug("initialize system acceptor...");
        }

        acceptor=new Acceptor();
        acceptor.setCorePoolSize(config.getInt(SOCKET_COREPOOLSIZE_KEY, 5));
        acceptor.setMaxPoolSize(config.getInt(SOCKET_MAXPOOLSIZE_KEY, 50));
        acceptor.setReuseAddress(config.getBoolean(SOCKET_REUSEADDRESS_KEY));
        acceptor.setReceiveBufferSize(config.getInt(SOCKET_RECEVIEBUFFERSIZE_KEY, 512));
        acceptor.setSendBufferSize(
                config.getInt(SOCKET_SENDBUFFERSIZE_KEY, 2048));
        acceptor.setTcpNoDelay(
                config.getBoolean(SOCKET_TCPNDELAY_KEY));
        acceptor.setIdleTime(
                config.getInt(SOCKET_IDLETIME_KEY, 180));
        acceptor.setPort(config.getInt(SOCKET_PORT_KEY, 8889));
    }

    /**
     * 初始系统配置接口 ISendInterceptor IDataProvider ISessionInterceptor
     */
    void initializeInterface(){
        if(log.isDebugEnabled()){
            log.debug("initialize system interface...");
        }

        /**
         * DataProvider
         */
        String className=config.get(DATA_PROVIDER_CLASS_KEY);
        if(null!=className){
            this.dataProvider=(IDataProvider) BeanUtil.newInstance(className);
        }

        /**
         * SendLListener
         */
        className=config.get(SEND_INTERCEPTOR_CLASS_KEY);
        if(null!=className){
            this.sendListener=(ISendListener) BeanUtil.newInstance(className);
        }

        /**
         * SessionListener
         */
        className=config.get(SESSION_INTERCEPTOR_CLASS_KEY);
        if(null!=className){
            this.sessionListener= (ISessionListener) BeanUtil.newInstance(className);
        }

        sendTask = new SendTask();
    }

    /**
     * 初始化任务队列
     */
    void initializeTaskQueue() {
        if(log.isDebugEnabled()){
            log.debug("initialize system task queue...");
        }
        taskQueue = new TaskQueue(config.getInt(SERVER_TASK_COREPOOLSIZE_KEY, 5),
                config.getInt(SERVER_TASK_MAXPOOLSIZE_KEY, 50));
    }

    /**
     * 初始化消息队列
     */
    void initializeMessageQueue(){
        if(log.isDebugEnabled()){
            log.debug("initialize system message queue...");
        }
//        messageQueue = new MessageQueue2 (this.dataProvider, config.getInt (PUSH_SCAN_TIME_KEY, 1000));
        messageQueue=new MessageQueue(this.dataProvider,
                this.sendTask,
                config.getInt(PUSH_COREPOOLSIZE_KEY, 5),
                config.getInt(PUSH_MAXPOOLSIZE_KEY, 50),
                config.getInt(PUSH_SCAN_TIME_KEY, 10)
        );
    }
    /**
     * 销毁　清空　释放
     */
    public  void destroy(){
        if(null != config)
            config.cleanUp();

    }

    public Acceptor getAcceptor(){
        if(null==acceptor){
            throw new NullPointerException("acceptor not init");
        }
        return acceptor;
    }

    public ISendListener getSendListener(){
        if(null==sendListener){
            throw new NullPointerException("send listener not init");
        }
        return sendListener;
    }

    public IDataProvider getDataProvider(){
        if(null==dataProvider){
            throw new NullPointerException("dataprovider not init");
        }
        return dataProvider;
    }

    public ISessionListener getSessionListener() {
        if(null==sessionListener){
            throw new NullPointerException("session listener not init");
        }
        return sessionListener;
    }

    public TaskQueue getTaskQueue() {
        return taskQueue;
    }

    public MessageQueue getMessageQueue() {
        return messageQueue;
    }

    public Config getConfig() {
        return config;
    }

    public String getDataDir() {
        return dataDir;
    }

    public String getConfDir() {
        return confDir;
    }

    public String getWorkDir() {
        return workDir;
    }

    public Config getAppConfig() {
        return appConfig;
    }

    public String getLogDir() {
        return logDir;
    }
}
